// Build with: gcc -o simple simple.c `pkg-config --libs --cflags mpv`

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

#include <mpv/client.h>
#include <string.h>

#include <alsa/asoundlib.h>
#include "sys/soundcard.h"

static char * alsa_mix_dev            = "default";
static char * alsa_mix_headphone_ctrl = "Headphone";

void volume_init(void)
{
    int alsa_mix_index                         = 0;
    snd_mixer_selem_id_t * alsa_mix_sid        = NULL;
    snd_mixer_t * alsa_mix_headphone_handle    = NULL;
    snd_mixer_elem_t * alsa_mix_headphone_elem = NULL;

    long min = 0, max = 0, curr = 0;

    snd_mixer_selem_id_alloca(&alsa_mix_sid);
    snd_mixer_selem_id_set_index(alsa_mix_sid, alsa_mix_index);
    snd_mixer_selem_id_set_name(alsa_mix_sid, alsa_mix_headphone_ctrl);

    if(snd_mixer_open(&alsa_mix_headphone_handle, 0) < 0) {
        printf("error 1\n");
    }
    if(snd_mixer_attach(alsa_mix_headphone_handle, alsa_mix_dev) < 0) {
        printf("error 2\n");
    }

    snd_mixer_selem_register(alsa_mix_headphone_handle, NULL, NULL);

    if(snd_mixer_load(alsa_mix_headphone_handle) < 0) {
        printf("error 3\n");
    }

    alsa_mix_headphone_elem = snd_mixer_find_selem(alsa_mix_headphone_handle, alsa_mix_sid);
    if(alsa_mix_headphone_elem == NULL) {
        printf("cannot find\n");
    }
    snd_mixer_selem_get_playback_volume_range(alsa_mix_headphone_elem, &min, &max);
    snd_mixer_selem_get_playback_volume(alsa_mix_headphone_elem, SND_MIXER_SCHN_UNKNOWN, &curr);
    printf("max: %ld,min: %ld, curr:%ld", max, min, curr);

    snd_mixer_selem_set_playback_volume_all(alsa_mix_headphone_elem, 63);
    snd_mixer_selem_set_playback_switch_all(alsa_mix_headphone_elem, 1);

    snd_mixer_close(alsa_mix_headphone_handle);
}

static inline void check_error(int status)
{
    if(status < 0) {
        printf("mpv API error: %s\n", mpv_error_string(status));
        exit(1);
    }
}

int main(int argc, char * argv[])
{
    if(argc != 2) {
        printf("pass a single media file as argument\n");
        return 1;
    }

    mpv_handle * ctx = mpv_create();
    if(!ctx) {
        printf("failed creating context\n");
        return 1;
    }

    volume_init();

    // Enable default key bindings, so the user can actually interact with
    // the player (and e.g. close the window).
    //    check_error(mpv_set_option_string(ctx, "input-default-bindings", "yes"));
    mpv_set_option_string(ctx, "input-vo-keyboard", "no");
    mpv_set_option_string(ctx, "vo", "null");
    mpv_observe_property(ctx, 0, "time-pos", MPV_FORMAT_DOUBLE);

    // Done setting up options.
    check_error(mpv_initialize(ctx));

    // Play this file.
    const char * cmd[] = {"loadfile", argv[1], NULL};
    check_error(mpv_command(ctx, cmd));

    // Let it play, and wait until the user quits.
    while(1) {
        mpv_event * event = mpv_wait_event(ctx, 10000);
        printf("event: %s\n", mpv_event_name(event->event_id));
        if(event->event_id == MPV_EVENT_PROPERTY_CHANGE) {
            mpv_event_property * prop = (mpv_event_property *)event->data;
            if(strcmp(prop->name, "time-pos") == 0) // 状态栏显示当前文件的播放时间（单位：秒）
            {
                if(prop->format == MPV_FORMAT_DOUBLE) // 属性数据的值格式是：double
                {
                    double time = *(double *)prop->data;
                    printf("pos = %.2f", time);
                } else if(prop->format == MPV_FORMAT_NONE) // 属性数据的值格式未知 (可能意味着播放已停止)
                {
                    //                    statusBar()->showMessage("");
                }
            }
        }
        if(event->event_id == MPV_EVENT_FILE_LOADED) {
            double data;
            mpv_get_property(ctx, "duration", MPV_FORMAT_DOUBLE, &data);
            printf("dura: %.2f\n", data);
        }
        if(event->event_id == MPV_EVENT_SHUTDOWN) break;
    }

    mpv_terminate_destroy(ctx);
    return 0;
}